// Epoller.hpp
#pragma once
#include <sys/epoll.h>
#include <unistd.h>
#include "nocopy.hpp"
#include "log.hpp"

class Epoller : public nocopy // 防拷贝
{
    static const int sz = 128;

public:
    Epoller()
    {
        _epfd = epoll_create(sz);
        if (_epfd == -1)
        {
            lg(Error, "epoll_create error: %s", strerror(errno));
        }
        lg(Info, "epoll_create success, fd: %d", _epfd);
    }
    int EpollerWait(struct epoll_event *revents, int num)
    {
        int n = epoll_wait(_epfd, revents, num, _timeout);
        return n;
    }
    int EpollerUpdate(int oper, int sock, uint32_t event)
    {
        int n = 0;
        if (oper == EPOLL_CTL_DEL)
        {
            n = epoll_ctl(_epfd, oper, sock, nullptr);
            if (n != 0)
            {
                lg(Error, "epoll_ctl delete error.");
            }
        }
        else
        {
            // EPOLL_CTL_MOD || EPOLL_CTL_ADD
            struct epoll_event ev;
            ev.events = event;
            ev.data.fd = sock;  // 方便后期处理事件时，得知是哪一个fd就绪了

            n = epoll_ctl(_epfd, oper, sock, &ev);
            if (n != 0)
            {
                lg(Error, "epoll_ctl error.");
            }
        }
        return n;
    }
    ~Epoller()
    {
        if (_epfd >= 0)
            close(_epfd);
    }

private:
    int _epfd;
    int _timeout{-1};
};